package com.itlong.cloud.iot.service.server.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.common.HuawIotAuthInfoDTO;
import com.itlong.cloud.POJO.DTO.common.HuawIotRegisterDTO;
import com.itlong.cloud.POJO.VO.common.IotInfoVO;
import com.itlong.cloud.POJO.VO.sdk.CloudControllerButtonStatusVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.iot.dao.IotInteriorDao;
import com.itlong.cloud.iot.huawei.util.HuawTokenClient;
import com.itlong.cloud.iot.service.server.HuawServerService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.sms.SmsMsgService;
import com.itlong.cloud.utils.network.https.HttpsPost;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *      iot公共基础服务接口华为实现类
 * </desc>
 *
 * @createDate 2020/01/02
 */
@Service
@RefreshScope
public class HuawServiceImpl implements HuawServerService{
    private static final Logger LOG = LoggerFactory.getLogger(HuawServiceImpl.class);
    @Autowired
    HuawTokenClient huawTokenClient;
    @Value("${" + PlatformConstants.HUAWEI_PROJECT_ID + "}")
    private String projectId;
    @Autowired
    IotInteriorDao iotInteriorDao;
    @Autowired
    RedisService redisService;

    @Autowired
    SmsMsgService smsMsgService;

    /**
     * <desc>
     *      发布消息
     * </desc>
     *
     * @param commandName  命令名称
     * @param deviceId  华为云iot设备id
     * @param msg 消息内容
     * @author Jiaqi.X
     * @createDate 2018/04/11
     */
    @Override
    public void pubDeviceMessage(String serviceId, String commandName, String deviceId, String msg) {
        try {
            String url = "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId + "/commands";
            Map<String, Object> params = new HashMap<>();
            LOG.info(String.format("【华为云发布消息msg】serviceId:%s commandName:%s msg:%s",serviceId,commandName,msg));
            Map<String, Object> paras = JsonUtil.toObject(msg, HashMap.class);
            params.put("service_id",serviceId);
            params.put("command_name",commandName);
            params.put("paras",paras);
            //监控请求时间是否过长
            long t1 = (new Date()).getTime();
            String result = HttpsPost.doPostV2(huawTokenClient.getAccessToken(), url, JsonUtil.toJSON(params), 5000);
            /*
            如果执行成功存到缓存里面
            result
            {
                "command_id": "8ad786f3-42e3-4ea8-9637-963288df9df1",
                "response": {
                    "result_code": 0,
                    "response_name": "cmdResponses",
                    "paras": {
                        "msg": "成功",
                        "msgCode": 0
                    }
                }
            }
            msg
            {
                "snr": "1074551542662725632",
                "cmd": "1001",
                "timeout": "300",
                "sourceFrom": "itlong",
                "timestamp": "1617957593801"
            }
            */
            JSONObject json = JSONObject.parseObject(result);
            if (json != null && json.containsKey("response")) {
                JSONObject response = json.getJSONObject("response");
                if (response.containsKey("paras") && response.getJSONObject("paras").getIntValue("msgCode") == 0) {
                    String snr = paras.get("snr").toString();
                    redisService.set(RedisConstant.REDIS_IOT_DEVICE_HANDLE_RESULT_CACHE + "_hw_" + snr, RedisConstant.REDIS_IOT_DEVICE_HANDLE_RESULT_CACHE_TIME, params);
                }
            }
            //
            long t2 = (new Date()).getTime();
            if (t2 - t1 >= 1000) {
                LOG.error("【http请求时间太长】{} {} {} {}", t2 - t1, result, deviceId, msg);
                //smsMsgService.sendSmsCodeByEmail("xxfaxy@qq.com", "[http请求时间太长]" + deviceId + " " + msg);
                //smsMsgService.sendSmsCodeByEmail("zhouc@itlong.com.cn", "[http请求时间太长]" + deviceId + " " + msg);
            }
            LOG.info("====================【华为云发布消息result】========================>{} {} {} {}", result, deviceId, params, msg);
        }catch (Exception e){
            LOG.error("【华为云发布消息失败：】",e);
        }
    }


    /**
     * <desc>
     *      发布消息并拿到消息结果
     * </desc>
     *
     * @param commandName  命令名称
     * @param deviceId  华为云iot设备id
     * @param msg 消息内容
     * @author Jiaqi.X
     * @createDate 2018/04/11
     */
    @Override
    public String pubDeviceMessageResponse(String serviceId, String commandName, String deviceId, String msg) {
        try {
            String url = "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId + "/commands";
            Map<String, Object> params = new HashMap<>();
            LOG.info(String.format("【华为云发布消息msg】serviceId:%s commandName:%s msg:%s",serviceId,commandName,msg));
            Map<String, Object> paras = JsonUtil.toObject(msg, HashMap.class);
            params.put("service_id",serviceId);
            params.put("command_name",commandName);
            params.put("paras",paras);
            String result = HttpsPost.doPost(huawTokenClient.getAccessToken(), url, JsonUtil.toJSON(params));
            return result;
        }catch (Exception e){
            LOG.error("【华为云发布消息失败：】",e);
            return null;
        }
    }

    /**
     * <desc>
     *      获取设备属性
     * </desc>
     *
     * @param commandName  命令名称
     * @param deviceId  华为云iot设备id
     * @param msg 消息内容
     * @author Jiaqi.X
     * @createDate 2018/04/11
     */
    @Override
    public void getProperties(String serviceId, String commandName, String deviceId, String msg) {
        try {
            String url = "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId + "/commands";
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> paras = JsonUtil.toObject(msg, HashMap.class);
            params.put("service_id",serviceId);
            params.put("command_name",commandName);
            params.put("paras",paras);
            String result = HttpsPost.doPost(huawTokenClient.getAccessToken(), url, JsonUtil.toJSON(params));
            System.out.println(result);
        }catch (Exception e){
            LOG.error("【华为云发布消息失败：】",e);
        }
    }

    /**
     * <desc>
     *     注册设备
     * </desc>
     *
     * @param iotInfoVO
     * @return
     * @throws Exception
     * @author Jiaqi.X
     * @createDate 2020/02/12
     */
    @Override
    public boolean registDevice(IotInfoVO iotInfoVO) throws Exception {
        String[] deviceUniques = StringHandlerUtil.splitString(iotInfoVO.getDeviceUnique());
        if(deviceUniques.length == 1) {
            HuawIotRegisterDTO huawIotRegisterDTO = new HuawIotRegisterDTO();
            huawIotRegisterDTO.setNode_id(StringHandlerUtil.getSnByDeviceUnique(iotInfoVO.getDeviceUnique()));
            huawIotRegisterDTO.setDevice_name(iotInfoVO.getDeviceUnique());
            huawIotRegisterDTO.setProduct_id(iotInfoVO.getIotProductKey());
            HuawIotAuthInfoDTO authInfo = new HuawIotAuthInfoDTO();
            authInfo.setAuth_type("SECRET");
            huawIotRegisterDTO.setAuth_info(authInfo);
            String result = HttpsPost.doPost(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices", JsonUtil.toJSON(huawIotRegisterDTO));
            LOG.info("【华为IOT注册入参及返回信息】{} {}", JsonUtil.toJSON(huawIotRegisterDTO), result);
            Map<String, Object> params = JsonUtil.toObject(result, HashMap.class);
            if(params.get("error_code") != null){
                redisService.del(RedisConstant.HUAWEI_ACCESS_TOKEN_REDIS_KEY);
                result = HttpsPost.doPost(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices", JsonUtil.toJSON(huawIotRegisterDTO));
                LOG.info("【华为IOT注册入参及返回信息】{} {}", JsonUtil.toJSON(huawIotRegisterDTO), result);
                params = JsonUtil.toObject(result, HashMap.class);
            }
            Map<String, Object> resultAuthInfo = (Map<String, Object>) params.get("auth_info");
            iotInteriorDao.updateDeviceIotInfo(iotInfoVO.getDeviceUnique(), params.get("device_id").toString(), resultAuthInfo.get("secret").toString(), huawIotRegisterDTO.getNode_id(), iotInfoVO.getDeviceType());
        }else{
            //云门禁
            //先查询设备
            String deviceId = projectId+"_"+StringHandlerUtil.getSnByDeviceUnique(deviceUniques[0]);
            String result = HttpsPost.doGet(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId, null);
            LOG.info("【华为IOT注册入参及返回信息】{} {}", deviceId, result);
            Map<String, Object> resultMap = JsonUtil.toObject(result, HashMap.class);
            if(resultMap.get("error_code") != null){
                redisService.del(RedisConstant.HUAWEI_ACCESS_TOKEN_REDIS_KEY);
                result = HttpsPost.doGet(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId, null);
                LOG.info("【华为IOT注册入参及返回信息】{} {}", deviceId, result);
                resultMap = JsonUtil.toObject(result, HashMap.class);
            }
            LOG.info("【注册查询华为云iot设备信息返回结果】"+JsonUtil.toJSON(resultMap));
            if(resultMap.get("device_id") != null){
                //查询当前门禁设备秘钥
                String devicePassword = iotInteriorDao.getEntranceHuaweiDevicePassword(deviceId);
                //更新门禁华为iot信息
                for(int i=0;i<deviceUniques.length;i++){
                    iotInteriorDao.updateDeviceIotInfo(iotInfoVO.getDeviceUnique(), resultMap.get("device_id").toString(), devicePassword, resultMap.get("node_id").toString(), iotInfoVO.getDeviceType());
                }
            }else {
                //注册设备
                HuawIotRegisterDTO huawIotRegisterDTO = new HuawIotRegisterDTO();
                huawIotRegisterDTO.setNode_id(StringHandlerUtil.getSnByDeviceUnique(deviceUniques[0]));
                huawIotRegisterDTO.setDevice_name(deviceUniques[0]);
                huawIotRegisterDTO.setProduct_id(iotInfoVO.getIotProductKey());
                HuawIotAuthInfoDTO authInfo = new HuawIotAuthInfoDTO();
                authInfo.setAuth_type("SECRET");
                huawIotRegisterDTO.setAuth_info(authInfo);
                String registResult = HttpsPost.doPost(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices", JsonUtil.toJSON(huawIotRegisterDTO));
                LOG.info("【华为IOT注册入参及返回信息】{} {}", JsonUtil.toJSON(huawIotRegisterDTO), registResult);
                Map<String, Object> params = JsonUtil.toObject(registResult, HashMap.class);
                if(params.get("error_code") != null){
                    redisService.del(RedisConstant.HUAWEI_ACCESS_TOKEN_REDIS_KEY);
                    registResult = HttpsPost.doPost(huawTokenClient.getAccessToken(), "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices", JsonUtil.toJSON(huawIotRegisterDTO));
                    LOG.info("【华为IOT注册入参及返回信息】{} {}", JsonUtil.toJSON(huawIotRegisterDTO), registResult);
                    params = JsonUtil.toObject(registResult, HashMap.class);
                }
                Map<String, Object> resultAuthInfo = (Map<String, Object>) params.get("auth_info");
                for (int i = 0; i < deviceUniques.length; i++) {
                    iotInteriorDao.updateDeviceIotInfo(deviceUniques[i], params.get("device_id").toString(), resultAuthInfo.get("secret").toString(), huawIotRegisterDTO.getNode_id(), iotInfoVO.getDeviceType());
                }
            }
        }
        return true;
    }

    /**
     * <desc>
     * 读取按键状态
     * <desc/>
     *
     * @param deviceId
     * @return
     * @author caoshuai
     * @createDate 2020/08/03
     */
    @Override
    public CloudControllerButtonStatusVO getButtonStatus(String deviceId) {
        CloudControllerButtonStatusVO cloudControllerButtonStatusVO = new CloudControllerButtonStatusVO();
        try {
            String serviceId = "SettingService";
            String commandName = "getButtonStatus";
            Map<String, Object> msgMap = new HashMap(16);
            msgMap.put("sourceFrom", "itlong");
            msgMap.put("snr", "1");
            msgMap.put("cmd", "1007");
            msgMap.put("timestamp", System.currentTimeMillis() + "");
            String url = "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/" + projectId + "/devices/" + deviceId + "/commands";

            Map<String, Object> params = new HashMap<>();
            LOG.info(String.format("【华为云发布消息msg】serviceId:%s commandName:%s msg:%s",serviceId,commandName,JSONObject.toJSONString(msgMap)));
            Map<String, Object> paras = msgMap;
            params.put("service_id",serviceId);
            params.put("command_name",commandName);
            params.put("paras",paras);

            String result = HttpsPost.doPost(huawTokenClient.getAccessToken(), url, JsonUtil.toJSON(params));
            Map<String, Object> resultMap = JSONObject.parseObject(result, HashMap.class);
            Map<String, Object> responseMap = JSONObject.parseObject(JSONObject.toJSONString(resultMap.get("response")), HashMap.class);
            cloudControllerButtonStatusVO = JSONObject.parseObject(JSONObject.toJSONString(responseMap.get("paras")), CloudControllerButtonStatusVO.class);
            if(StringUtils.isNotBlank(cloudControllerButtonStatusVO.getError_code())){
                cloudControllerButtonStatusVO.setMsgCode(500);
                cloudControllerButtonStatusVO.setMsg(cloudControllerButtonStatusVO.getError_msg());
                LOG.error("【读取按键状态失败：】",cloudControllerButtonStatusVO.getError_msg());
            }

        } catch (IOException e) {
            LOG.error("【读取按键状态失败：】",e);
            //程序异常
            cloudControllerButtonStatusVO.setMsgCode(500);
        }
        return cloudControllerButtonStatusVO;
    }
//    public static void main(String[] args) throws IOException {
//        HuawIotRegisterDTO huawIotRegisterDTO = new HuawIotRegisterDTO();
//        huawIotRegisterDTO.setNode_id("0000012200000001");
//        huawIotRegisterDTO.setDevice_name("0000012210001");
//        huawIotRegisterDTO.setProduct_id("产品key");
//        HuawIotAuthInfoDTO authInfo = new HuawIotAuthInfoDTO();
//        authInfo.setAuth_type("SECRET");
//        huawIotRegisterDTO.setAuth_info(authInfo);
//        System.out.println(JsonUtil.toJSON(huawIotRegisterDTO));
//    }
}